package testvolatile;

/**
 * @Package: testvolatile
 * @ClassName: VolatileTestAgain
 * @Author: lujieni
 * @Description: 123
 * @Date: 2021-04-07 11:16
 * @Version: 1.0
 */
public class VolatileTestAgain implements Runnable {
    private ObjectA a;

    public VolatileTestAgain(ObjectA a) {
        this.a = a;
    }

    public ObjectA getA() {
        return a;
    }

    public void setA(ObjectA a) {
        this.a = a;
    }

    /**
     * @Description:
     *  1.在ObjectA中 volatile ObjectASub sub,ObjectASub sub = a.getSub(); 仍旧有问题 个人认为是本地线程的ObjectASub不是volatile的
     *  2.ObjectA不用volatile修饰,但ObjectA.ObjectASub用volatile修饰, a.getSub().isFlag()没有问题
     *
     *
     *
     * @param
     * @return:
     * @Author: lujieni
     * @Date: 2021/4/7
     */
    @Override
    public void run() {
        long i = 0;
        ObjectASub sub = a.getSub();
        boolean flag = sub.flag;
        while (!sub.flag) { // a.getSub().isFlag() 这样写才可以
            i++;
        }
        System.out.println("stop My Thread " + i);
    }

    public static void main(String[] args) throws Exception {
        System.out.println(System.getProperty("java.vm.name"));
        ObjectASub sub = new ObjectASub();
        ObjectA sa = new ObjectA();
        sa.setSub(sub);
        VolatileTestAgain test = new VolatileTestAgain(sa);
        new Thread(test).start();

        Thread.sleep(1000);
        sub.setFlag(true);
        System.out.println("Main Thread " + sub.isFlag());
    }

    static class ObjectA {
        private  ObjectASub sub;

        public ObjectASub getSub() {
            return sub;
        }
        public void setSub(ObjectASub sub) {
            this.sub = sub;
        }
    }

    static class ObjectASub{
        private volatile boolean flag;

        public boolean isFlag() {
            return flag;
        }

        public void setFlag(boolean flag) {
            this.flag = flag;
        }
    }
}